function [ varargout ] = subsref( this, s )
%SUBSREF Subscript reference @DataMatrix object
% DataMatrix::subsref( this:DataMatrix, 
%                      s:struct )
%           >>         varargout
% 
% Description
% 
% Input
% 1. this
% 2. s
% 
% Output
% 1. varargout
% 
% Syntax
% ~. this.propertyName
% ~. this.methodName
% ~. this(
% 
% Example
% 

switch s(1).type
    case '()' % Return the double form matrix
        % Check inputs
        subs = s.subs;
        nSubs = length(subs);
        switch nSubs
            case 0
                sub1 = ':';
                sub2 = ':';
            case 1
                sub1 = subs{1};
                sub2 = ':';
            case 2
                sub1 = subs{1};
                sub2 = subs{2};
            otherwise
                error('BatErr: Invalid subscripts.');
        end
        
        % Get the (sub-)matrix
        [varargout{1:nargout}] = this.getMat(sub1, sub2);
        
    case '{}' % Return a @DataMatrix object
        % Check inputs
        subs = s.subs;
        nSubs = length(subs);
        switch nSubs
            case 1
                sub1 = subs{1};
                sub2 = ':';
            case 2
                sub1 = subs{1};
                sub2 = subs{2};
            otherwise
                error('BatErr: Invalid subscripts.');
        end
        
        % Get the data matrix info
        name = this.name;
        mat = this.getMat(sub1, sub2);
        zRowName = this.getZRowName(sub1);
        zColName = this.getZColName(sub2);
        
        % Generate the @DataMatrix object
        varargout{1} = DataMatrix(name, mat, zRowName, zColName);
        
        % Post processing
        for iArgOut = 2:nargout
            varargout{iArgOut} = [];
        end
        
    case '.' % Call the built-in methods
        [varargout{1:nargout}] = builtin('subsref', this, s);
        
    otherwise
        error('BatErr: Invalid subscripts.');
end

end
